package com.corder.display.controller;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Random;

import com.corder.display.dao.CreateKey;
import com.corder.display.dao.User;
import com.corder.display.util.Constant;
import com.corder.display.util.DesCrypt;
import com.corder.display.util.EncryptionTool;
import com.corder.display.util.SystemUtil;
import com.corder.display.validator.LoginStatusValidator;
import com.corder.display.validator.LoginTokenValidator;
import com.jfinal.aop.Before;
import com.jfinal.core.Controller;

public class UserController extends Controller {
	/*
	 * 初始化方法 
	 */
	public void index() {
		// setSessionAttr("path", getRequest().getContextPath());
		// 初始化token
		createToken("login_token", 5 * 60);
		setAttr("path", getRequest().getContextPath());
		render("/WEB-INF/view/back/login.html");
	}

	/**
	 * 用户登录验证
	 */
	@Before({ LoginTokenValidator.class })
	public void logining() throws UnsupportedEncodingException {
		try {
			//清空提示信息
			removeCookie("Constant.LOGIN_ALTER_MSG");
			//获取访问者的真实ip
			String ip = SystemUtil.getIp(getRequest());
			User user = getModel(User.class);
			String firstKey = getPara("firstKey");
			String secondKey = getPara("secondKey");
			String thirdKey = getPara("thirdKey");
			String password = DesCrypt.getInstance().strDec(user.getStr("password"), firstKey, secondKey, thirdKey);
			user.set("password", EncryptionTool.makeMD5(password));
			setAttr("path", getRequest().getContextPath());
			SimpleDateFormat sf = new SimpleDateFormat("yy-MM-dd hh-mm-ss");
			if (User.dao.checkUser(user) != null
					&& User.dao.checkUser(user).size() == 1) {
				User tmp = User.dao.checkUser(user).get(0);
				String uuid = EncryptionTool.getUUID();
				tmp.set("loginTimes", tmp.getInt("loginTimes") + 1)
				   .set("lastLoginTime", sf.format(new Date())).set("loginToken", uuid).set("ip", ip).set("lastModifyTime", System.currentTimeMillis()).update();
				setAttr("chinessName", tmp.getStr("chineseName"));
				//将登陆用户id存入cookie中，时间为10分钟
				setCookie("loginToken", uuid, 10 * 60 * 1000);
				render("/WEB-INF/view/back/index.html");
			} else {
				setCookie(Constant.LOGIN_ALTER_MSG,
						URLEncoder.encode("您输入的用户名或密码不正确", "utf-8"), 5 * 60 * 1000);
				redirect("/back");
			}
		} catch(Exception e) {
			setCookie(Constant.LOGIN_ALTER_MSG,
					URLEncoder.encode("系统出现异常，请稍后重试！", "utf-8"), 5 * 60 * 1000);
			e.printStackTrace();
			redirect("/back");
		}
		/*System.out.println("解密后的字段:" + password);
		String uuid = getCookie("uuid");
		if (uuid == null || uuid.trim() == null) {
			removeCookie("p", "/");
			removeCookie("g", "/");
			removeCookie("Ya", "/");
			removeCookie("Yb", "/");
			removeCookie("uuid", "/");
			setCookie(Constant.LOGIN_ALTER_MSG,
					URLEncoder.encode("登陆超时，请重试！", "utf-8"), 5 * 60 * 1000);
			redirect("/back");
			return;
		}
		CreateKey createKey = CreateKey.dao.findFirst(
				"select * from createKey where uuid = ?",
				new Object[] { uuid });
		int p = createKey.getInt("prime");
		int Xa = createKey.getInt("random");
		int Yb = Integer.parseInt(getCookie("Yb"));
		int k = (int) (Math.pow(Yb, Xa) % p);
		String[] strs = user.getStr("password").split(",");
		byte[] bytes = new byte[strs.length];
		for (int i = 0; i < strs.length; i++) {
			bytes[i] = (byte) (Integer.parseInt(strs[i]) - k);
		}
		System.out.println("解密后的字段：" + new String(bytes));*/
	}

	/**
	 * 初始化导航栏 
	 */
	@ Before(LoginStatusValidator.class)
	public void initNavigationBar(){
		renderText("初始化导航栏不正确");
	}
	
	/**
	 * 为登陆密码加密做准备 
	 */
	public void updateKey() {
		try {
			//清空cookie
			removeCookie("p", "/");
			removeCookie("g", "/");
			removeCookie("Ya", "/");
			removeCookie("Yb", "/");
			removeCookie("uuid", "/");
			//生成大素数
			Long p = EncryptionTool.createRadomPrimeNunber(4);
			//获取根数
			int g = EncryptionTool.g;
			//生成随机数Xa
			int Xa = new Random().nextInt(31);
			//计算Ya
			int Ya = (int) (Math.pow(g, Xa) % p);
			//获取uuid
			String uuid = EncryptionTool.getUUID();
			//获取UUID，作为主键，记录随机数Xa和生成时间，同时将过期的记录删除
			CreateKey.dao.put("uuid", uuid)
						 .put("id", null)
						 .put("prime", p)
			             .put("random", Xa)
			             .put("createTime", System.currentTimeMillis()).save();
			List<CreateKey> list = CreateKey.dao.find(
					"select * from createKey where createTime <= ?",
					System.currentTimeMillis() - 5 * 60 * 1000);
			for (CreateKey createKey : list) {
				CreateKey.dao.deleteById(createKey.getLong("id"));
			}
			setCookie("p", p.toString(), 5 * 60);
			setCookie("g", g + "", 5 * 60);
			setCookie("Ya", Ya + "", 5 * 60);
			setCookie("uuid", uuid, 5 * 60);
			renderText("success");
		} catch (Exception e) {
			renderText("fail");
		}
		
		/*Long p = EncryptionTool.createRadomPrimeNunber(4);
		int g = EncryptionTool.g;
		int Xa = new Random().nextInt(31);
		int Ya = (int) (Math.pow(g, Xa) % p);
		CreateKey.dao.set("prime", p).set("random", Xa)
				.set("keyId", p.toString() + Xa).set("id", null)
				.set("createTime", System.currentTimeMillis()).save();
		List<CreateKey> list = CreateKey.dao.find(
				"select * from createKey where createTime <= ?",
				System.currentTimeMillis() - 5 * 60 * 1000);
		for (CreateKey createKey : list) {
			CreateKey.dao.deleteById(createKey.getLong("id"));
		}
		setCookie("p", p.toString(), 5 * 60);
		setCookie("g", g + "", 5 * 60);
		setCookie("Ya", Ya + "", 5 * 60);
		setCookie("keyId", p.toString() + Xa, 5 * 60);
		renderNull();*/
	}

	/**
	 * 登出服务 
	 */
	public void loginOut() {
		//清除数据库的登陆状态
		String loginToken = getCookie("loginToken");
		if(loginToken != null && !loginToken.trim().equals("")) {
			//如果有loginToken，则清除该token对应的登陆信息
			User user = User.dao.findFirst("select * from user where loginToken = ?", new Object[]{loginToken});
			user.set("loginToken", "").set("ip", "").set("lastModifyTime", 9999999999999l).update();
		} else {
			//如果loginToken没找到，则清除数据库中已经过期了的登陆信息
			List<User> userList = User.dao.find("select * from user where lastModifyTime <= ?", System.currentTimeMillis()-Constant.LOGIN_MISSING_TIME*60*1000);
			for (User user : userList) {
				user.set("loginToken", "").set("ip", "").set("lastModifyTime", 9999999999999l).update();
			}
		}
		redirect("/back");
	}
}
